package com.basaji.dao.manager;


import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.basaji.domain.pojo.BaseObject;


@SuppressWarnings("unchecked")
public class PojoManager<T extends BaseObject> extends HibernateDaoSupport {

	//private static Log log = LogFactory.getLog(PojoManager.class);
	Logger log = Logger.getLogger(PojoManager.class);

	/**
	 * save object
	 * @param basePojo
	 * @throws Exception
	 */

	public void save(BaseObject basePojo) throws Exception {

		try {
			this.getHibernateTemplate().save(basePojo);
		} catch (Exception e) {
			log.error("save: " + basePojo.getClass().getName() + " "+ e.getMessage());
			throw new Exception("save:"+e.getMessage());
		}
	}
	

	/**
	 * update Pojo
	 * @param basePojo
	 * @throws Exception
	 */

	public void update(BaseObject basePojo) throws Exception {
		try {
			this.getHibernateTemplate().saveOrUpdate(basePojo);
		} catch (Exception e) {
			log.error("update: " + basePojo.getClass().getName() + " "+ e.getMessage());
			throw new Exception("update:"+e.getMessage());
		}
	}

	public void saveOrUpdate(BaseObject basePojo) throws Exception {
		try {
			this.getHibernateTemplate().saveOrUpdate(basePojo);
		} catch (Exception e) {
			log.error("update: " + basePojo.getClass().getName() + " "+ e.getMessage());
			throw new Exception("saveOrUpdate:"+e.getMessage());
		}
	}
	/**
	 * delete
	 * @param basePojo
	 * @throws Exception
	 */
	public void delete(T basePojo) throws Exception {
		try {
			this.getHibernateTemplate().delete(basePojo);
		} catch (Exception e) {
			log.error("delete: " + basePojo.getClass().getName() + " "+ e.getMessage());
			throw new Exception("delete:"+e.getMessage());
		}
	}

	/**
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public BaseObject getOneByID(Class<? extends BaseObject> clazz, Serializable id) throws Exception {
		try {
			if (clazz == null || id == null){				
				return null;
			}else{				
				return (BaseObject) this.getHibernateTemplate().load(clazz, id);
			}
		} catch (Exception e) {
			log.error("getOneByID: " + clazz.getName() + " "+ e.getMessage());
			throw new Exception("loadByID"+e.getMessage());
		}
	}
	
	public  <E> List<E>  getListByWhere(String where,Object[] objects, int start, int size) throws Exception {
		return this.getListByWhere(where, objects, start, size,true);
	}
	
	public  <E> List<E>  getListByWhere(String where,Object[] objects, int start, int size,boolean CACHE) throws Exception {
		Session session = this.getSession();
		List<E> _list = new ArrayList<E>();
		try {
			Transaction tx = session.beginTransaction();
			Query query = session.createQuery(where);
			if(objects != null ){
				int objectsize = objects.length;
				if(objectsize>0){
					for(int i = 0; i < objectsize; i++){
						query.setParameter(i, objects[i]);
					}
				}
			}
			query.setFirstResult(start);
			query.setMaxResults(size);
			query.setCacheable(CACHE);//允许把查询加入缓孄1�7
			_list = query.list();
			tx.commit();
		} catch (Exception e) {
			session.close();
			_list = null;
			log.debug("loadListByWhere: "+ e.getMessage());
			throw new Exception("executeSql:"+ e.getMessage());
		}
		session.close();
		return _list;
	}
	
	
	
	
	/**
	 * 
	 * @param <E>
	 * @param where
	 * @param start
	 * @param size
	 * @param cache
	 * @return
	 * @throws Exception
	 */
	public  <E> List<E>  getListByWhere(String where, int start, int size,boolean CACHE) throws Exception {
		
		return (List<E>) this.getList(where, null, start, size);
	}
	
	

	/**
	 * 
	 * @param sql
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public int executeSql(String sql) throws Exception {
		int result = 0;
		Session session = this.getSession();
		Transaction ts = session.beginTransaction();
		Connection con = session.connection();
		try {
			PreparedStatement stmt = con.prepareStatement(sql);
			result = stmt.executeUpdate();
			ts.commit();
			stmt.close();
		} catch (Exception e) {
			ts.rollback();
			log.debug("executeSql: " + sql + e.getMessage());
			throw new Exception("executeSql:"+e.getMessage());
		}
		con.close();
		session.close();
		return result;
	}
	/**
	 * 
	 * 
	 * @param where
	 * @return
	 * @throws Exception
	 */
	public Integer getIntCount(String where,Object[] objects) throws Exception {
		Integer counts = 0;
		
		Long _l = (Long)this.getCount(where, objects, true);
		
		if(_l != null){
			counts = _l.intValue();
		}
		return counts;

	}
	public Object getCount(String where,Object[] objects,boolean CACHE) throws Exception {
		Session session = this.getSession();
		Object obj = new Object();
		try {
			Query query = session.createQuery(where);
			if(objects!=null){
				int objectsize = objects.length;
				if(objectsize>0){
					for(int i = 0; i < objectsize; i++){
						query.setParameter(i, objects[i]);
					}
				}
			}
			
			if (query == null) {
				return null;
			}
			obj = query.uniqueResult();
		} catch (Exception e) {
			obj = null;
			session.close();
			log.error("getCount: " + where + " "+ e.getMessage());
			throw new Exception("getCount"+e.getMessage());
		}
		session.close();
		return obj;
	}
	
	public void deleteList(String where,Object[] objects) throws Exception{
		Session session = this.getSession();
		try {
			
			Transaction tx = session.beginTransaction();
			Query query = session.createQuery(where);
			int objectsize = objects.length;
			if(objectsize>0){
				for(int i = 0; i < objectsize; i++){
					query.setParameter(i, objects[i]);
				}
			}
			query.executeUpdate();
			tx.commit();
	        
		} catch (Exception e) {
			session.close();
			log.error("deleteList: " + where + " "+ e.getMessage());
			throw new Exception("deleteList:"+e.getMessage());
		}
		session.close();
	}
/**
	@SuppressWarnings({ "unchecked", "unused", "rawtypes" })
	public List<T> getList(final Class<? extends T> clazz,final int start,final int size){
	
		return (List) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(final Session session) throws HibernateException {
            	Query q = session.createQuery("from "+clazz.getName()+" order by id asc");
            	q.setFirstResult(start);
        		q.setMaxResults(size);
                return q.list();
            }
        });
	}
	
	@SuppressWarnings({ "unchecked", "unused", "rawtypes" })
	public List<T> getList(final Class<? extends T> clazz,final String field,final Object value,final int start,final int size){
	
		return (List) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(final Session session) throws HibernateException {
            	Query q = session.createQuery("from "+clazz.getName()+" where "+field+"=? order by id asc");
            	q.setParameter(0, value);
            	q.setFirstResult(start);
        		q.setMaxResults(size);
                return q.list();
            }
        });
	}
	*/
	public List<T> getList(final String sql,final Object[] values,final int start,final int size){
		
		return (List) getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(final Session session) throws HibernateException {
            	Query q = session.createQuery(sql);
            	if(values != null && values.length >0){
	        		for(int i = 0; i < values.length; i++){
	        			q.setParameter(i, values[i]);
	        		}
	        	}
            	q.setFirstResult(start);
        		q.setMaxResults(size);
                return q.list();
            }
        });
	}
	
}
